﻿using ApplicationBase.Core.Logs;
using LogDashboard.Application.Model;
using LogDashboard.Application.Utils;

namespace LogDashboard.Application.Services
{
    public class LogParseService
    {
        public static List<CacheDataModel> cacheDataModels = new();
        public static Dictionary<string, Dictionary<DateTime, int>> CacheLineChartData = new();
        public static List<UowDataModel> uowDataModels = new();

        public void ParseLog(Stream logStream)
        {
            var parser = new LogParser();
            parser.Parse(logStream);

            cacheDataModels = ParseCacheData(parser.CacheLogs);
            ParseCacheLineChart(cacheDataModels);

            uowDataModels = ParseUnitOfWorkData(parser.UnitOfWorkLogs);
        }

        private List<CacheDataModel> ParseCacheData(List<CacheLog> logs)
        {
            List<CacheDataModel> list = new();

            var group = logs.GroupBy(it => it.Key).Select(it => new
            {
                Value = logs.Where(l => l.Key == it.Key).ToList()
            }).ToList();

            foreach (var item in group)
            {
                list.Add(new CacheDataModel(item.Value));
            }

            return list;
        }

        private void ParseCacheLineChart(List<CacheDataModel> list) 
        {
            Dictionary<string, Dictionary<DateTime, int>> dict = new();
            foreach (var model in list)
            {
                Dictionary<DateTime, int> TimeCountDict = new();
                var firstLog = model.CacheLogs[0];
                var timeSpan = firstLog.HoldTime!;

                var startTime = firstLog.Time;
                var endTime = firstLog.Time.AddMilliseconds(timeSpan.Value.TotalMilliseconds);
                var count = 1;

                int index = 1;
                while (index < model.CacheLogs.Count)
                {
                    var log = model.CacheLogs[index];
                    if (log.Time < endTime)
                    {
                        count++;
                        index++;
                    }
                    else
                    {
                        TimeCountDict.Add(startTime, count);
                        startTime = startTime.AddMilliseconds(timeSpan.Value.TotalMilliseconds);
                        endTime = endTime.AddMilliseconds(timeSpan.Value.TotalMilliseconds);
                        count = 0;
                    }
                }
                TimeCountDict.Add(startTime, count);

                dict.Add(model.Key, TimeCountDict);
            }

            CacheLineChartData = dict;
        }

        private List<UowDataModel> ParseUnitOfWorkData(List<UnitOfWorkLog> logs)
        {
            List<UowDataModel> list = new();

            var group = logs.GroupBy(it => it.Name).Select(it => new
            {
                Value = logs.Where(l => l.Name == it.Key).ToList()
            }).ToList();

            foreach (var item in group)
            {
                list.Add(new UowDataModel(item.Value));
            }

            return list;
        }
    }
}
